﻿using AvalonDock.Layout;
using CommunityToolkit.Mvvm.Messaging;
using DeviceControl;
using LuaConsole;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using Modbus.Device;
using Serilog;
using Serilog.Filters;
using ServoDrivesLib.Controls;
using ServoDrivesLibAbstract;
using System.Configuration;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.IO.Ports;
using System.Reflection;
using System.Reflection.PortableExecutable;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using 雷赛板卡上位机.Models;
using 雷赛板卡上位机.Services;
using 雷赛板卡上位机.View;
using 雷赛板卡上位机.ViewModel;
using ServoDrivesLib.Model;
using ControlType = ServoDrivesLib.Model.ControlType;

namespace 雷赛板卡上位机
{
    /// <summary>
    /// 交互逻辑App.xaml
    /// </summary>
    public partial class App : Application
    {
        public static IHost? MyHost { get; set; }

        [STAThread]
        static void Main(string[] args)
        {
            MyHost = CreateHostBuilder(args).Build(); // 创建并构建主机实例
            MyHost?.Start(); // 启动主机
            var app = new App();
            app.InitializeComponent(); // 初始化应用程序组件
            app.MainWindow = MyHost?.Services.GetRequiredService<BootView>(); // 获取主窗口服务
            app.MainWindow.Visibility = Visibility.Visible; // 设置主窗口可见
            app.Run(); // 运行应用程序
        }

        private static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(cb =>
                {
                    cb.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
                    cb.AddEnvironmentVariables();
                })
                // 创建默认的主机生成器
                .ConfigureServices(container =>
                {
                    container.AddSingleton<BootView>(sp => new BootView
                    {
                        DataContext = sp.GetRequiredService<BootViewModel>()
                    }); // 注册BootView单例，并设置数据上下文为BootViewModel
                    container.AddSingleton<BootViewModel>(); // 注册BootViewModel单例
                    container.AddSingleton<MainWindowView>(); // 注册MainWindowView单例

                    container.AddSingleton<MenuBarView>(sp => new MenuBarView
                    {
                        DataContext = App.GetService<MenuBarViewModel>()
                    }); // 注册MenuBarView单例，并设置数据上下文为MenuBarViewModel
                    container.AddSingleton<MenuBarViewModel>(); // 注册MenuBarViewModel单例
                    container.AddSingleton<SidebarView>(sp => new SidebarView
                    {
                        DataContext = App.GetService<SideberViewModel>()
                    }); // 注册SidebarView单例，并设置数据上下文为SideberViewModel
                    container.AddSingleton<SideberViewModel>(); // 注册SideberViewModel单例
                                                                // container.AddSingleton<AxisItemTreeData>();

                    container.AddSingleton<TabControlViewModel>(); // 注册TabControlViewModel单例
                    container.AddSingleton<IMessenger, WeakReferenceMessenger>();
                    container.AddSingleton<Assembly>(sp => Assembly.GetExecutingAssembly());
                    container.AddSingleton(_ => Current.Dispatcher);

                    container.AddSingleton<LeisaiControlCard>(); //注册雷赛板卡控制类
                    container.AddSingleton<ZMoitionControl>();  //注册正运动控制器控制类

                    container.AddSingleton<LuaMaster>();
                    container.AddSingleton<InputTextBox>(sp => new InputTextBox
                    {
                        DataContext = App.GetService<InputTextBoxViewModel>()
                    }); // 注册InputTextBox单例，并设置数据上下文为InputTextBoxViewModel
                    container.AddSingleton<InputTextBoxViewModel>(); // 注册InputTextBoxViewModel单例
                    container.AddSingleton<IPopUpService, PopUpService>();
                    container.AddSingleton<AvalonDockView>(sp => new AvalonDockView { DataContext = App.GetService<TabContorlModel>() });
                    container.AddSingleton<CardControlManager>((sp) =>
                    {
                        var card = CardControlManager.Instance;
                        card.Register(ControlType.Leisai.ToString(), App.GetService<LeisaiControlCard>());
                        card.Register(ControlType.ZMonition.ToString(), App.GetService<ZMoitionControl>());
                        return card;
                    }); //注册板卡单例

                    container.AddTransient<AxisControlView>(sp => new AxisControlView
                    {
                        DataContext = App.GetService<AxisControlViewModel>()
                    }); // 注册AxisControlView单例，并设置数据上下文为AxisControlViewModel

                    container.AddTransient<AxisControlViewModel>(); // 注册AxisControlViewModel单例
                    container.AddTransient<OpenFileDialog>();
                    container.AddTransient<SerialPort>();
                    container.AddTransient<ModbusRtu>();
                    container.AddTransient<ProgreeBarView>();
                    container.AddTransient<LayoutDocument>();


                })
                .ConfigureLogging(logging =>
                {
                    // 清空默认日志提供程序
                    logging.ClearProviders();
                    // 添加控制台和Debug输出日志
                    Log.Logger = new LoggerConfiguration()
                        .WriteTo.Logger(cfg =>
                        {
                            cfg.Filter.ByIncludingOnly(Matching.FromSource<LeisaiControlCard>());
#if RELEASE
                            cfg.WriteTo.Console();
#else
                            cfg.WriteTo.File("logs/CardLog.txt", rollingInterval: RollingInterval.Day,
                                retainedFileCountLimit: 7,
                                outputTemplate:
                                "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}");
#endif
                        })
                        .WriteTo.Logger(cfg =>
                        {
                            cfg.Filter.ByIncludingOnly(Matching.FromSource<雷赛板卡上位机.App>());
#if RELEASE
                            cfg.WriteTo.Console();
#else
                            cfg.WriteTo.File("logs/VisibleLog.txt", rollingInterval: RollingInterval.Day,
                                retainedFileCountLimit: 7,
                                outputTemplate:
                                "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}");
#endif
                        })
                        .WriteTo.Logger(cfg =>
                        {
                            cfg.Filter.ByIncludingOnly(Matching.FromSource<LuaMaster>());
#if RELEASE
                            cfg.WriteTo.Console();
#else
                            cfg.WriteTo.File("logs/LuaLog.txt", rollingInterval: RollingInterval.Day,
                                retainedFileCountLimit: 7,
                                outputTemplate:
                                "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}");
#endif
                        })
                        .CreateLogger();
                    logging.AddSerilog();
                    // logging.AddConsole();
                    // logging.AddDebug();
                });
        }

        public static T GetService<T>() where T : class
        {
            return MyHost?.Services.GetRequiredService(typeof(T)) as T; // 获取指定类型的单例服务
        }

        public static T GetService<T>(ControlType controlType) where T : class
        {
            var tmp = MyHost?.Services.GetKeyedServices(typeof(T), controlType);
            return tmp.FirstOrDefault() as T;
        }
        protected override void OnExit(ExitEventArgs e)
        {
            var close = App.GetService<TabControlViewModel>();
            foreach (var t in close.Dock)
            {
                ((IDisposable)t.Content).Dispose();
            }
            //Thread.Sleep(500);
            this.Dispose();

            base.OnExit(e);
        }
        public async void Dispose()
        {
            await MyHost?.StopAsync(); // 异步停止主机
            MyHost?.Dispose(); // 释放主机资源
        }


    }

    public static class ObjEx
    {
        public static void Dispose(this object obj)
        {
            Type type = obj.GetType();
            foreach (var t in type.GetMethods())
            {
                if (t.Name == "Dispose")
                {
                    ((IDisposable)obj).Dispose();
                }
            }
        }
    }
}